package com.nicole.reqresp.filters;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.parser.Feature;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.servlet.HandlerMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.*;

/**
 * @author  xiaoying
 */
@Slf4j
public class RequestUtils {
    /**
     * 获取所有的请求头
     */
    @org.jetbrains.annotations.NotNull
    public static Map<String,String> getHeaders(HttpServletRequest request){
        Map<String,String> headerMap = new HashMap<>();
        List<String> headers = getCommonHeaders();
        headers.add("Postman-Token");
        headers.add("Proxy-Connection");
        headers.add("X-Lantern-Version");
        headers.add("Cookie");
        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()){
            String headerName = headerNames.nextElement();
            if (headers.contains(headerName)){
                continue;
            }
            headerMap.put(headerName,request.getHeader(headerName));
        }
        return headerMap;
    }
    /**
     * 获取请求的路径参数
     */
    public static Map<String, String> getUriTemplateVar(HttpServletRequest request) {
        NativeWebRequest webRequest = new ServletWebRequest(request);
        return (Map<String, String>) webRequest.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, RequestAttributes.SCOPE_REQUEST);
    }
    /**
     * 获取请求的真实IP
     */
    public static String getRealIP(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
            //多次反向代理后会有多个ip值，第一个ip才是真实ip
            int index = ip.indexOf(",");
            if (index != -1) {
                return ip.substring(0, index);
            } else {
                return ip;
            }
        }
        ip = request.getHeader("X-Real-IP");
        if (StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
            return ip;
        }
        return request.getRemoteAddr();
    }
    /**
     * @return Map<String,String>
     */
    public static Map<String,String> getRequestParamMap(HttpServletRequest httpServletRequestWrapper, HttpServletRequest request) {
        Map<String,String> paramMap = new HashMap<>();
        //获取QueryString中的参数，GET方式 或application/x-www-form-urlencoded
        String queryString = request.getQueryString();
        if (StringUtils.isNotBlank(queryString)){
            paramMap.put("queryString",queryString);
        }
        // form-data请求参数
        Map<String, String[]> parameterMap = request.getParameterMap();
        if(!parameterMap.isEmpty()){
            for (Map.Entry<String, String[]> stringEntry : parameterMap.entrySet()) {
                String[] value = stringEntry.getValue();
                StringBuilder stringBuffer = new StringBuilder();
                for (String s : value) {
                    stringBuffer.append(s);
                }
                paramMap.put(stringEntry.getKey(),stringBuffer.toString());
            }
        }
        try {
            //当为POST请求且 application/json时，request被RequestFilter处理为wrapper类
            if (!(request instanceof MyRequestBodyReaderWrapper)){
                return paramMap;
            }
            MyRequestBodyReaderWrapper myRequestBodyReaderWrapper = (MyRequestBodyReaderWrapper) httpServletRequestWrapper;
            String requestBody = myRequestBodyReaderWrapper.getBody(request);
            if (StringUtils.isNotBlank(requestBody)){
                Object parse = JSON.parse(requestBody);
                if(parse instanceof JSONObject){
                    Map<String,String>  bodyParamMap = JSONObject.parseObject(requestBody, new TypeReference<LinkedHashMap<String,String>>(){}, Feature.OrderedField);
                    if (bodyParamMap != null){
                        paramMap.putAll(bodyParamMap);
                    }
                }else if(parse instanceof JSONArray){
                    paramMap.put("list",requestBody);
                }else{
                    log.error("无效类型，无法转换");
                }
            }
        } catch (Exception e) {
            log.error("获取请求Body异常-->",e);
        }
        return paramMap;
    }
    private static List<String> getCommonHeaders(){
        List<String> headers = new ArrayList<>();
        Class<HttpHeaders> clazz = HttpHeaders.class;
        Field[] fields = clazz.getFields();
        for (Field field : fields) {
            field.setAccessible(true);
            if (field.getType().toString().endsWith("java.lang.String") && Modifier.isStatic(field.getModifiers())){
                try {
                    headers.add((String) field.get(HttpHeaders.class));
                } catch (IllegalAccessException e) {
                    log.error("反射获取属性值异常-->",e);
                }
            }
        }
        return headers;
    }
}
